package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exception.LyException;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import com.netflix.discovery.converters.Auto;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import static com.leyou.common.constants.MQConstants.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@SuppressWarnings("ALL")
/**
 * @Description :
 * @author     :LD
 */
@Service
@Transactional
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SpuDetailService spuDetailService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public PageDTO<SpuDTO> querySpuByPage(Integer page, Integer size, Boolean saleable, Long categoryId, Long brandId, Long id) {
        //分页调价检查
        page=Math.max(page,1);
        size=Math.max(size,5);
        //准备查询条件， SELECT * FROM tb_spu WHERE saleable = ? AND category_id = ? AND brand_id = ? AND id = ?
        Page<Spu> result = query()
                .eq(saleable!=null,"saleable",saleable)
                .eq(categoryId!=null,"cid3",categoryId)
                .eq(brandId!=null,"brand_id",brandId)
                .eq(id!=null,"id",id)
                .page(new Page<>(page,size));

        long total = result.getTotal();
        long pages = result.getPages();
        List<Spu> records = result.getRecords();

        List<SpuDTO> dtoList = SpuDTO.convertEntityList(records);
        for (SpuDTO dto : dtoList) {
            //获取分类名和品牌名
            handleCategoryAndBrandName(dto);
        }

        return new PageDTO<>(total,pages,dtoList);
    }

    private void handleCategoryAndBrandName(SpuDTO dto) {
        //查询品牌名称
        Brand brand = brandService.getById(dto.getBrandId());
        if (brand!=null){
            dto.setBrandName(brand.getName());
        }
        //获取分类名称
        List<Category> categories = categoryService.listByIds(dto.getCategoryIds());
        if (CollectionUtils.isNotEmpty(categories)){
            String collect = categories.stream().map(Category::getName).collect(Collectors.joining("/"));
            dto.setCategoryName(collect);
        }
    }

    @Override
    public void saveGoods(SpuDTO spuDTO) {
        //新增spu
        Spu spu = spuDTO.toEntity(Spu.class);
        spu.setSaleable(false);
        boolean success = save(spu);
        if (!success){
            throw new LyException(500,"新增商品失败");
        }
        //新增spudetails
        SpuDetail spuDetail = spuDTO.getSpuDetail().toEntity(SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        success=spuDetailService.save(spuDetail);
        if(!success){
            throw new LyException(500,"新增商品详情失败");
        }
        //新增sku
        List<Sku> skus = spuDTO.getSkus().stream().map(skuDTO -> {
            Sku sku = skuDTO.toEntity(Sku.class);
            sku.setSaleable(false);
            sku.setSpuId(spu.getId());
            return sku;
        }).collect(Collectors.toList());
        skuService.saveBatch(skus);
    }

    @Override
    public void updateSaleable(Long id, Boolean saleable) {
        //1 更新spu
        Spu spu = new Spu();
        spu.setSaleable(saleable);
        spu.setId(id);
        boolean success = updateById(spu);
        if (!success){
            throw new LyException(500,"更新失败");
        }
        //2 更新sku
        success=skuService.update().eq("spu_id",id).set("saleable",saleable).update();
        if (!success){
            throw new LyException(500,"更新失败");
        }

        //3 发送mq消息
        String routingKey = saleable?RoutingKeyConstants.ITEM_UP_KEY:RoutingKeyConstants.ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ExchangeConstants.ITEM_EXCHANGE_NAME,routingKey,id);
    }

    @Override
    public SpuDTO  getSpuById(Long id) {
        //查询spu
        Spu spu = getById(id);
        if (spu==null){
            throw new LyException(400,"商品id不存在");
        }
        SpuDTO spuDTO = new SpuDTO(spu);
        //查询spuDetail
        SpuDetail spuDetail = spuDetailService.getById(id);
        if (spuDetail==null){
            throw new LyException(400,"商品id不存在");
        }
        spuDTO.setSpuDetail(new SpuDetailDTO(spuDetail));
        //查询sku
        List<Sku> skus = skuService.query().eq("spu_id", id).list();
        if (CollectionUtils.isEmpty(skus)){
            throw new LyException(400,"商品id不存在");
        }
        spuDTO.setSkus(SkuDTO.convertEntityList(skus));
        return spuDTO;
    }

    @Override
    public void updateGood(SpuDTO spuDTO) {
        //1、修改spu
        Long spuId = spuDTO.getId();
        if (spuId!=null){
            boolean b = updateById(spuDTO.toEntity(Spu.class));
            if (!b){
                throw new LyException(500,"更新商品失败");
            }
        }
        //2、修改spuDetaill
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        if (spuDetailDTO!=null&&spuDetailDTO.getSpuId()!=null){
            boolean b = spuDetailService.updateById(spuDetailDTO.toEntity(SpuDetail.class));
            if (!b){
                throw new LyException(500,"更新商品失败");
            }
        }
        //3、修改sku
        List<SkuDTO> skus = spuDTO.getSkus();
        if (CollectionUtils.isEmpty(skus)){
            return;
        }
        //转换DTO，并将sku根据saleable是否为null来分组。null，是新增或修改，不是null是删除
        Map<Boolean, List<Sku>> map = skus.stream()
                .map(skuDTO -> skuDTO.toEntity(Sku.class))
                .collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));
        //新增或修改
        List<Sku> skus1 = map.get(true);
        if (CollectionUtils.isNotEmpty(skus1)){
            skuService.saveOrUpdateBatch(skus1);
        }
        //删除
        List<Sku> skus2 = map.get(false);
        if (CollectionUtils.isNotEmpty(skus2)){
            List<Long> ids = skus2.stream().map(Sku::getId).collect(Collectors.toList());
            skuService.removeByIds(ids);
        }

    }
}
